#pragma once

#include <cstddef>

/**
 * @brief 第四版本：析构函数负责释放资源。
 *
 * 新增析构函数，在对象生命周期结束时，如果托管指针非空，
 * 调用删除器执行资源释放。
 */
template <typename T, typename Deleter = void(*)(T*)>
class UniquePtr {
public:
    using pointer      = T*;
    using element_type = T;
    using deleter_type = Deleter;

    static void default_delete(T* ptr) noexcept {
        delete ptr;
    }

    constexpr UniquePtr() noexcept
        : ptr_(nullptr)
        , deleter_(default_delete) {}

    constexpr UniquePtr(std::nullptr_t) noexcept
        : UniquePtr() {}

    explicit UniquePtr(pointer ptr) noexcept
        : ptr_(ptr)
        , deleter_(default_delete) {}

    /**
     * @brief 析构函数。
     *
     * 如果当前持有资源，调用删除器释放。
     */
    ~UniquePtr() {
        if (ptr_) {
            deleter_(ptr_);
        }
    }

    pointer get() const noexcept {
        return ptr_;
    }

    element_type& operator*() const noexcept {
        return *ptr_;
    }

    pointer operator->() const noexcept {
        return ptr_;
    }

    explicit operator bool() const noexcept {
        return ptr_ != nullptr;
    }

private:
    pointer      ptr_;
    deleter_type deleter_;
};